using Circus.CodeEditor;
using Circus.Syntax.Design;

using System;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace Circus.Syntax.Lexer
{
	[TypeConverter(typeof(LexSchemeConverter))]
	[Serializable]
	public class LexScheme {
		private string author = string.Empty;
		private string name = string.Empty;
		private string desc = string.Empty;
		private string copyright = string.Empty;
		private string version = SyntaxConsts.DefaultLexSchemeVersion;
		private string fileExtension = string.Empty;
		private string fileType = string.Empty;
		private LexStates states;
		private LexStyles styles;
		private Circus.Syntax.Lexer.Lexer owner;
		[Description("Gets or sets author of the \"LexScheme\".")]
		public virtual string Author
		{
			get
			{
				return this.author;
			}
			set
			{
				if (this.author != value)
				{
					this.author = value;
					this.OnAuthorChanged();
				}
			}
		}
		[Description("Gets or sets \"LexScheme\" name.")]
		public virtual string Name
		{
			get
			{
				return this.name;
			}
			set
			{
				if (this.name != value)
				{
					this.name = value;
					this.OnNameChanged();
				}
			}
		}
		[Description("Gets or sets description of the \"LexScheme\".")]
		public virtual string Desc
		{
			get
			{
				return this.desc;
			}
			set
			{
				if (this.desc != value)
				{
					this.desc = value;
					this.OnDescChanged();
				}
			}
		}
		[Description("Gets or sets copyright of the \"LexScheme\".")]
		public virtual string Copyright
		{
			get
			{
				return this.copyright;
			}
			set
			{
				if (this.copyright != value)
				{
					this.copyright = value;
					this.OnCopyrightChanged();
				}
			}
		}
		[Description("Gets or sets string value indicating associated file extension of the \"ILexScheme\".")]
		public virtual string FileExtension
		{
			get
			{
				return this.fileExtension;
			}
			set
			{
				if (this.fileExtension != value)
				{
					this.fileExtension = value;
					this.OnFileExtensionChanged();
				}
			}
		}
		[Description("Gets or sets string value indicating associated file type of the \"ILexScheme\".")]
		public virtual string FileType
		{
			get
			{
				return this.fileType;
			}
			set
			{
				if (this.fileType != value)
				{
					this.fileType = value;
					this.OnFileTypeChanged();
				}
			}
		}
		[Description("Gets or sets version of the \"LexScheme\".")]
		public virtual string Version
		{
			get
			{
				return this.version;
			}
			set
			{
				if (this.version != value)
				{
					this.version = value;
					this.OnVersionChanged();
				}
			}
		}
		[Description("Gets or sets collection of lexical styles.")]
		public virtual LexStyles Styles
		{
			get
			{
				return this.styles;
			}
			set
			{
				this.styles.Clear();
				foreach (LexStyle current in value)
				{
					this.styles.Add(current);
				}
				this.OnStylesChanged();
			}
		}
		[Description("Gets or sets collection of lexical states.")]
		public virtual LexStates States
		{
			get
			{
				return this.states;
			}
			set
			{
				this.states.Clear();
				foreach (LexState current in value)
				{
					this.states.Add(current);
				}
				this.OnStatesChanged();
			}
		}
	
		protected void Init()
		{
			this.OnStatesChanged();
		}
		protected virtual LexStyle GetLexStyle(int index)
		{
			return (index >= 0 && index < this.styles.Count) ? this.styles[index] : null;
		}
		protected virtual LexState GetLexState(int index)
		{
			return (index >= 0 && index < this.states.Count) ? this.states[index] : null;
		}
		protected virtual void OnStylesChanged()
		{
		}
		protected virtual void OnStatesChanged()
		{
		}
		protected virtual void OnAuthorChanged()
		{
		}
		protected virtual void OnNameChanged()
		{
		}
		protected virtual void OnDescChanged()
		{
		}
		protected virtual void OnCopyrightChanged()
		{
		}
		protected virtual void OnFileExtensionChanged()
		{
		}
		protected virtual void OnFileTypeChanged()
		{
		}
		protected virtual void OnVersionChanged()
		{
		}
		public LexScheme(Circus.Syntax.Lexer.Lexer owner)
		{
			this.owner = owner;
			this.states = new LexStates(this);
			this.styles = new LexStyles(this);
		}
		public virtual bool IsEmpty()
		{
			return this.styles.Count == 0 && this.states.Count == 0 && this.author == string.Empty && this.name == string.Empty && this.desc == string.Empty && this.copyright == string.Empty && this.fileType == string.Empty && this.fileExtension == string.Empty;
		}
		public virtual bool IsPlainText(int style)
		{
			return style >= 0 && style < this.styles.Count && this.styles[style].PlainText;
		}
		public virtual void Clear()
		{
			this.styles.Clear();
			this.states.Clear();
			this.author = string.Empty;
			this.name = string.Empty;
			this.desc = string.Empty;
			this.copyright = string.Empty;
			this.version = SyntaxConsts.DefaultLexSchemeVersion;
			this.fileExtension = string.Empty;
			this.fileType = string.Empty;
		}
		public virtual void Update()
		{
			if (this.owner != null)
			{
				this.owner.Update();
			}
		}
		public virtual bool LoadFile(string fileName)
		{
			return this.LoadFile(fileName, null);
		}
		public virtual bool LoadFile(string fileName, Encoding encoding)
		{
			bool result;
			try
			{
				Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
				try
				{
					TextReader textReader = (encoding != null) ? new StreamReader(stream, encoding) : new StreamReader(stream);
					try
					{
						result = this.LoadStream(textReader);
					}
					finally
					{
						textReader.Close();
					}
				}
				finally
				{
					stream.Close();
				}
			}
			catch (Exception exception)
			{
				ErrorHandler.Error(exception);
				result = false;
			}
			return result;
		}
		public virtual bool LoadStream(TextReader reader) {
		    return false;
		}
		public virtual bool LoadStream(Stream stream)
		{
			return this.LoadStream(stream, null);
		}
		public virtual bool LoadStream(Stream stream, Encoding encoding)
		{
			TextReader textReader = (encoding != null) ? new StreamReader(stream, encoding) : new StreamReader(stream);
			bool result;
			try
			{
				result = this.LoadStream(textReader);
			}
			finally
			{
				textReader.Close();
			}
			return result;
		}
		public virtual bool SaveFile(string fileName)
		{
			return this.SaveFile(fileName, null);
		}
		public virtual bool SaveFile(string fileName, Encoding encoding)
		{
			bool result;
			try
			{
				Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
				try
				{
					StreamWriter streamWriter = new StreamWriter(stream);
					try
					{
						result = this.SaveStream(streamWriter);
					}
					finally
					{
						streamWriter.Close();
					}
				}
				finally
				{
					stream.Close();
				}
			}
			catch (Exception exception)
			{
				ErrorHandler.Error(exception);
				result = false;
			}
			return result;
		}
		public virtual bool SaveStream(TextWriter writer)
		{
			return false;
		}
		public virtual bool SaveStream(Stream stream)
		{
			return this.SaveStream(stream, null);
		}
		public virtual bool SaveStream(Stream stream, Encoding encoding)
		{
			TextWriter textWriter = (encoding != null) ? new StreamWriter(stream, encoding) : new StreamWriter(stream);
			bool result;
			try
			{
				result = this.SaveStream(textWriter);
			}
			finally
			{
				textWriter.Close();
			}
			return result;
		}
	}
}
